import { Data3DTexture, DataTexture, DoubleSide, ShaderMaterial, Texture, Vector2, Vector3 } from "three";

/** 空间剖面材质 */
export const Space_Profile_Material = new ShaderMaterial({
  transparent: true,
  uniforms: {
    u_min: {
      value: new Vector3()
    },
    u_max: {
      value: new Vector3(1, 1, 1)
    },
    u_legend: {
      value: new Texture()
    },
    u_data: {
      value: new Data3DTexture(new Float32Array([-1000000000]), 1, 1, 1)
    },
    u_range: {
      value: [0, 1]
    },
    u_opacity: {
      value: 0.7
    },
    u_filter: {
      value: [-100000000, 100000000]
    }
  },
  side: DoubleSide,
  vertexShader: `
 
  varying vec3 v_position;
  void main(){
        vec4 mPosition=modelMatrix  * vec4(position,1.0);
        v_position= mPosition.xyz/mPosition.w;
        gl_Position=projectionMatrix * viewMatrix * mPosition;
  }
  `,
  fragmentShader: `
  precision mediump sampler3D;
  uniform vec3 u_min;
  uniform vec3 u_max;
  uniform sampler3D u_data;
  uniform sampler2D u_legend;
  uniform float u_range[2];
  uniform float u_filter[2];
  uniform float u_opacity;
  varying vec3 v_position;

  void main(){
    vec3 uvw=(v_position-u_min)/(u_max-u_min);
    if(all(greaterThan(uvw,vec3(0.0,0.0,0.0)))&&all(lessThan(uvw,vec3(1.0,1.0,1.0)))){
      float value=texture(u_data, uvw).r;
      if(value>=u_filter[0]&&value<=u_filter[1]){
        float u=(value-u_range[0])/(u_range[1]-u_range[0]);
        vec4 color=texture2D(u_legend,vec2(u,0.5));
        color.a = color.a*u_opacity;
        gl_FragColor=color;
      }else{
        discard;
      }
    }else{
      discard;
    }
  }
  `
})


/** 水平等值面材质 */
export const Horizontal_Isosurface_Material = new ShaderMaterial({
  transparent: true,
  uniforms: {
    u_min: {
      value: new Vector2(0,0)
    },
    u_max: {
      value: new Vector2(1, 1)
    },
    u_legend: {
      value: new Texture()
    },
    u_data: {
      value: new DataTexture(new Float32Array([-1000000000]), 1, 1)
    },
    u_range: {
      value: [0, 1]
    },
    u_opacity: {
      value: 0.7
    },
    u_filter: {
      value: [-100000000, 100000000]
    }
  },
  side: DoubleSide,
  vertexShader: `
 
  varying vec3 v_position;
  void main(){
        vec4 mPosition=modelMatrix  * vec4(position,1.0);
        v_position= mPosition.xyz/mPosition.w;
        gl_Position=projectionMatrix * viewMatrix * mPosition;
  }
  `,
  fragmentShader: `
  uniform vec2 u_min;
  uniform vec2 u_max;
  uniform sampler2D u_data;
  uniform sampler2D u_legend;
  uniform float u_range[2];
  uniform float u_filter[2];
  uniform float u_opacity;
  varying vec3 v_position;

  void main(){
    vec2 uv=(v_position.xy-u_min)/(u_max-u_min);
    // gl_FragColor=vec4(u_max,0.0,1.0);
    if(all(greaterThan(uv,vec2(0.0,0.0)))&&all(lessThan(uv,vec2(1.0,1.0)))){
      float value=texture(u_data, uv).r;
      if(value>=u_filter[0]&&value<=u_filter[1]){
        float u=(value-u_range[0])/(u_range[1]-u_range[0]);
        vec4 color=texture2D(u_legend,vec2(u,0.5));
        color.a = color.a*u_opacity;
        gl_FragColor=color;
      }else{
        discard;
      }
    }else{
      discard;
    }
  }
  `
})


/** 空间垂直剖面材质 */
export const Vertical_Profile_Material=new ShaderMaterial({
  transparent: true,
  uniforms: {
    u_min: {
      value: new Vector3()
    },
    u_max: {
      value: new Vector3(1, 1, 1)
    },
    u_legend: {
      value: new Texture()
    },
    u_data: {
      value: new Data3DTexture(new Float32Array([-1000000000]), 1, 1, 1)
    },
    u_range: {
      value: [0, 1]
    },
    u_opacity: {
      value: 0.7
    },
    u_filter: {
      value: [-100000000, 100000000]
    },
    u_hfilter: {
      value: [500*20,14000*20],
    },
  },
  side: DoubleSide,
  vertexShader: `
 
  varying vec3 v_position;
  void main(){
        vec4 mPosition=modelMatrix  * vec4(position,1.0);
        v_position= mPosition.xyz/mPosition.w;
        gl_Position=projectionMatrix * viewMatrix * mPosition;
  }
  `,
  fragmentShader: `
  precision mediump sampler3D;
  uniform vec3 u_min;
  uniform vec3 u_max;
  uniform sampler3D u_data;
  uniform sampler2D u_legend;
  uniform float u_range[2];
  uniform float u_filter[2];
  uniform float u_hfilter[2];
  uniform float u_opacity;
  varying vec3 v_position;

  float step=10000.0;
  float stepD2=5000.0;

  void main(){
    vec3 c2p=v_position-cameraPosition;

    float delta=length(c2p)*0.001;

    if(abs(mod(v_position.z,step)-stepD2)>stepD2-delta){
      gl_FragColor=vec4(1.0,1.0,1.0,1.0);
    }else{
      vec3 uvw=(v_position-u_min)/(u_max-u_min);
      float value=texture(u_data, uvw).r;
      
      if(v_position.z>=u_hfilter[0]&& v_position.z<=u_hfilter[1]&& value>=u_filter[0]&&value<=u_filter[1]){
        float u=(value-u_range[0])/(u_range[1]-u_range[0]);
        vec4 color=texture2D(u_legend,vec2(u,0.5));
        color.a = color.a*u_opacity;
        gl_FragColor=color;
      }else{
        discard;
      }
    }
  }
  `,
})

/** 空间体积材质 */
export const Space_Volume_Material=new ShaderMaterial({
  transparent: true,
  uniforms: {
    u_min: {
      value: new Vector3()
    },
    u_max: {
      value: new Vector3(1, 1, 1)
    },
    u_legend: {
      value: new Texture()
    },
    u_data: {
      value: new Data3DTexture(new Float32Array([-1000000000]), 1, 1, 1)
    },
    u_range: {
      value: [0, 1]
    },
    u_opacity: {
      value: 0.7
    },
    u_filter: {
      value: [-100000000, 100000000]
    },
    u_min_mask: {
      value: new Vector2()
    },
    u_max_mask: {
      value: new Vector2(1, 1)
    },
    u_mask:{
      value:new Texture()
    }
  },
  // side: DoubleSide,
  vertexShader: `
 
  varying vec3 v_position;
  void main(){
        vec4 mPosition=modelMatrix  * vec4(position,1.0);
        v_position= mPosition.xyz/mPosition.w;
        gl_Position=projectionMatrix * viewMatrix * mPosition;
  }
  `,
  fragmentShader: `
  precision mediump sampler3D;
  uniform vec3 u_min;
  uniform vec3 u_max;
  uniform sampler3D u_data;
  uniform sampler2D u_legend;
  uniform vec2 u_min_mask;
  uniform vec2 u_max_mask;
  uniform sampler2D u_mask;
  uniform float u_range[2];
  uniform float u_filter[2];
  uniform float u_opacity;
  varying vec3 v_position;

  void main(){

    vec3 c2p=v_position.xyz-cameraPosition;
    vec3 dirction=normalize(c2p);
    float ls=length(c2p);
    float le=ls+100000000000.0;
    //计算射线与长方体交点
   
    float l1=(u_min.x-cameraPosition.x)/dirction.x;
    float l2=(u_max.x-cameraPosition.x)/dirction.x;
    float l3=(u_min.y-cameraPosition.y)/dirction.y;
    float l4=(u_max.y-cameraPosition.y)/dirction.y;
    float l5=(u_min.z-cameraPosition.z)/dirction.z;
    float l6=(u_max.z-cameraPosition.z)/dirction.z;

    if(l1-ls>1.0&&l1<le) le=l1;
    if(l2-ls>1.0&&l2<le) le=l2;
    if(l3-ls>1.0&&l3<le) le=l3;
    if(l4-ls>1.0&&l4<le) le=l4;
    if(l5-ls>1.0&&l5<le) le=l5;
    if(l6-ls>1.0&&l6<le) le=l6;

    float step=(le-ls)/64.0;
    float value=-100000000000.0;
    float anchor=ls;

    vec3 min2max=u_max-u_min;
    vec2 minm2maxm=u_max_mask-u_min_mask;
    for(int i=0;i<65;i++){
      vec3 pst=dirction*anchor+cameraPosition;
      vec3 uvw=(pst-u_min)/min2max;
      vec2 uv=(pst.xy-u_min_mask)/minm2maxm;
      float r=texture(u_data, uvw).r;
      float a=texture2D(u_mask, uv).a;
      if(a>0.0&&r>value&&r<=u_filter[1]) value=r;
      anchor+=step;
    }
    if(value>=u_filter[0]){
      float u=(value-u_range[0])/(u_range[1]-u_range[0]);
    vec4 color=texture2D(u_legend,vec2(u,0.5));
    color.a = color.a*u_opacity;
    
    gl_FragColor=color;
    }else{
      discard;
    }
    
  }
  `
})